using System.ComponentModel.Design;
using Microsoft.Practices.WizardFramework;
using Sixeyed.CodeGeneration.Metadata;
using Sixeyed.Guidance.CodeGeneration.CodeGeneration;
using wizard = Microsoft.WizardFramework;

namespace Sixeyed.Guidance.CodeGeneration.CustomWizardPages
{
    /// <summary>
    /// Base class for code generation wizard pages
    /// </summary>
    /// <remarks>
    /// Custom metadata sources can be loaded by specifying a <see cref="Sixeyed.CodeGeneration.Metadata.SourceAssemblyConfiguration"/>
    /// element in the recipe argument calling this page. Specifying configuration will bypass the relevant page.
    /// </remarks>
    public partial class CodeGenerationPageBase : CustomWizardPageBase
    {
        private static SourceAssemblyConfiguration sourceAssemblyConfiguration;
        private static Metadata metadata;
        
        /// <summary>
        /// Gets shared metadata settings
        /// </summary>
        protected static Metadata Metadata
        {
            get
            {
                if (metadata == null)
                {
                    metadata = new Metadata();
                }
                return metadata;
            }
        }

        /// <summary>
        /// Default constructor
        /// </summary>
        public CodeGenerationPageBase() { }

        /// <summary>
        /// Constructor with initial state
        /// </summary>
        /// <param name="parent">Parent wizard form</param>
        public CodeGenerationPageBase(WizardForm parent)
            : base(parent)
        {
            SetSourceAssemblyConfiguration(parent);
        }

        /// <summary>
        /// Disposes
        /// </summary>
        /// <param name="disposing">Whether disposing</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                metadata = null;
            }
            base.Dispose(disposing);
        }

        /// <summary>
        /// Enables/disables the Next or Finish button
        /// </summary>
        protected void EnableNextStep()
        {
            if (this.IsDataValid)
            {
                wizard.ButtonType buttonType = (this.Wizard.NextPage == null ? wizard.ButtonType.Finish : wizard.ButtonType.Next);
                this.Wizard.EnableButton(buttonType, true);
            }
        }

        /// <summary>
        /// Loads metadata sources and providers from configured settings
        /// </summary>
        /// <remarks>
        /// If no configuration settings are provided in the recipe, loads the known sources
        /// in Sixeyed.CodeGeneration for user to select source and provider
        /// </remarks>
        /// <param name="parent"></param>
        private static void SetSourceAssemblyConfiguration(WizardForm parent)
        {
            //if source assemblies not set, use default or configured value:
            if (sourceAssemblyConfiguration == null)
            {
                IDictionaryService dictionary = (IDictionaryService)parent.ServiceProvider.GetService(typeof(IDictionaryService));
                sourceAssemblyConfiguration = dictionary.GetValue("SourceAssemblyConfiguration") as SourceAssemblyConfiguration;
                if (sourceAssemblyConfiguration == null)
                {
                    sourceAssemblyConfiguration = new SourceAssemblyConfiguration();
                }
                SourceContainer.SourceAssemblyConfiguration = sourceAssemblyConfiguration;
            }
        }

        private struct ArgumentName
        {
            public const string SourceAssemblyConfiguration = "SourceAssemblyConfiguration";
        }

        private void InitializeComponent()
        {
            ((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
            this.SuspendLayout();
            // 
            // infoPanel
            // 
            this.infoPanel.Location = new System.Drawing.Point(0, 0);
            this.infoPanel.Size = new System.Drawing.Size(600, 275);
            // 
            // CodeGenerationPageBase
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.InfoRTBoxSize = new System.Drawing.Size(0, 0);
            this.Name = "CodeGenerationPageBase";
            this.Size = new System.Drawing.Size(600, 275);
            ((System.ComponentModel.ISupportInitialize)(this)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }
    }
}